/*
 * octal.c
 *
 */
#include "octal.h"
// graba en un archivo el valor en octal
// del numero guardado en c.
void grabar(char c, FILE *f){
	switch (c) {
		case 0:
		fputc('0',f);
		break;
		case 1:
		fputc('1',f);
		break;
		case 2:
		fputc('2',f);
		break;
		case 3:
		fputc('3',f);
		break;
		case 4:
		fputc('4',f);
		break;
		case 5:
		fputc('5',f);
		break;
		case 6:
		fputc('6',f);
		break;
		case 7:
		fputc('7',f);
		break;
	}
}

//convierte el octal en decimal
int convertir(char c, int i){
	int mult;
	//estos if son porque me tira error al hacer pow(8,i)
	if (i == 2){
		mult = 64;
	}
	else if(i == 1){
		mult = 8;
	}
	else {
		mult = 1;
	}
	switch (c) {
		case 48://char 48 vale 0
		// no aporta nada al decimal hacer mid = mid + mult*0;
		break;
		case 49://char 49 vale 1
			return mult*1;
		break;
		case 50://char 50 vale 2
			return mult*2;
		break;
		case 51://char 51 vale 3
			return mult*3;
		break;
		case 52://char 52 vale 4
			return mult*4;
		break;
		case 53://char 53 vale 5
			return mult*5;
		break;
		case 54://char 54 vale 6
			return mult*6;
		break;
		case 55://char 55 vale 7
			return mult*7;
		break;

	}
	return 0;
}

void codificar(FILE *f,FILE *fout, char *delimitador, int len){
	// Resto es el char (paquete de 8 bits) leido del archivo.
    char resto = 0;
    // Cantidad de bits sin procesar en el resto
    char bitsSobrantes = 0;
    int first_read = 0;
    int cantOctales = 0;
    resto = fgetc(f);

    while (!feof(f)) {
		// si no hay bits sobrantes, el resto fue procesado por completo,
		// entonces leo un nuevo byte
        if (bitsSobrantes==0) {
			first_read = 0;
			bitsSobrantes = 8;
		}
		// Comienzo a leer de a tres bits en el resto
		// haciendo corrimientos y los grabo al archivo de salida
        char terna;
        if (first_read == 0){
        	terna = (resto >> 6 );
        	grabar(terna,fout);
        	bitsSobrantes -= 2;
        	first_read = 1;
        }
		while (bitsSobrantes>=3){
			//terna = ( (resto << (8-bitsSobrantes) ) >> 5 );
        //int result = (x >> lsb) & ~(~0 << (msb-lsb+1));
		/*	terna = (resto >> 3) & ~(~0 << (3));
			printf("%lu\n",terna);
			grabar(terna,fout);
			bitsSobrantes -= 3;*/
			terna = (resto >> (bitsSobrantes-3)) & ~(~0 << (3));
			/*printf("%lu\n",terna);*/
			grabar(terna,fout);
			bitsSobrantes -= 3;
		}

		fputs(delimitador,fout);
		if((cantOctales==len)&&(len!=0))
			fputs("\n",fout);
		cantOctales++;

		resto = fgetc(f);
    }
}

void decodificar(FILE *f,FILE *fout, char *delimitador){
	char bin;
	int i;
	//char *dest;
	int mid = 0;
	int j,k;

	j = sizeof(delimitador)/sizeof(char);
	bin = fgetc(f);
	while(!feof(f)){
	    	//bin = fgetc(f);
	    	//val = atoi(bin);
	    	//printf("%lu\n",bin);
	    	for ( i = 2; i>=0; i--){
	    		/*dec = val*64 + dec;
	    		bin = fgetc(f);
	    		val = atoi(bin);
	    		dec = val*8 + dec;
	    		bin = fgetc(f);
	    		val = atoi(bin);
	    		dec = val + dec;*/
	    		//ReturnCode = fgets(del, strlen(delimitador),f);
	    		//printf("%lu\n",dec);
	    		//bin = fgetc(f);
	    		//en mid voy sumando la conversion del octal a decimal
	    		mid = mid + convertir(bin,i);
	    		bin = fgetc(f);
	    	}
	    	//printf(mid);
	    	//convierto en char el decimal que obtuve a partir del octal, y lo escribo en el archivo
	    	fputc((char)mid,fout);
	    	mid = 0;
	    	//salteo el delimitador
	    	for (k=j;k>=1;k--){
	    		bin = fgetc(f);
	    	}
	    //	free(dest);
	    //	strtol (dest, NULL,8);
	}

}

/*int main(void) {
	char *delimitador= "delimitador";
	//descomentar si se quiere probar el codificador
    FILE* fin = fopen("test.bin","rb");//fopen(argv[1],"rb");
    codificar(fin, delimitador);
    fclose(fin);
	//descomentar si se quiere probar el codificador, y cambiar medio.txt por salida.txt para probar con
    //la salida del codificador
    FILE* fmedio = fopen("salida.txt","rt");
    decodificar(fmedio, delimitador);
    fclose(fmedio);
    return EXIT_SUCCESS;
}*/


